<template>
  <div class="echarts-wall" :style="echartsStyle">
    <div class="dot-bg" v-if="loading"></div>
    <div class="dot-elastic dotClass" v-if="loading"></div>
    <div class="echarts-content" ref="echartsDom"></div>
  </div>
</template>

<script lang="ts" setup>
// @ts-ignore
import {ElMessage} from "element-plus";
// @ts-ignore
import screenConfig, {getMarkPoint} from '@/components/global/bigscreen/screen_config'

defineOptions({
  name: "EchartsBar"
});
// @ts-ignore
import {getCurrentInstance, onMounted, ref, watch} from "vue";

const loading = ref<boolean>(false);

const props = defineProps({
      //横向top 展示 name 和 value
      horizontal: {type: Boolean, default: false},
      //横向top 展示 name 和 value
      horizontalNameColor: {type: String, default: "#FFF"},
      //横向top 展示 name 和 value
      horizontalValueColor: {type: String, default: "#FFF"},
      horizontalNameFontSize: {type: Number, default: 14},
      horizontalValueFontSiz: {type: Number, default: 12},

      //自定义分割
      customSymbol: {type: Boolean, default: false},
      //富文本样式
      richBar: {type: Boolean, default: false},
      //数组排序
      richNumBar: {type: Boolean, default: false},
      //数组排序
      richLineValue: {type: Boolean, default: false},
      //bar 颜色
      barColor: {
        type: Array, default() {
          return ['#00A3E0']
        }
      },
      //bar 宽度
      barWidth: {
        type: Number, default: screenConfig.barWidth,
      },
      //上下展示层叠加
      barStack: {type: Boolean, default: false},
      //单一分类是的bar 处理itemStyle
      singBaseModel: {type: Boolean, default: false},
      //竖立显示名称
      erectName: {type: Boolean, default: false},
      //显示legend
      legendShow: {type: Boolean, default: false},
      legendOrient: {type: String, default: 'vertical'},//vertical
      legendLeft: {type: String, default: 'left'},//vertical
      //显示数据值
      seriesLabelShow: {type: Boolean, default: false},
      //值的位置
      seriesLabelPosition: {type: String, default: 'top'},
      //值的位置
      seriesLabelColor: {type: String, default: 'red'},
      seriesItemStyle: {type: Object, default: {normal: {}}},
      //显示y轴value值
      yAxisLabelShow: {type: Boolean, default: false},
      //y轴分割线
      yAxisSplitLineShow: {type: Boolean, default: false},
      //y轴分割线颜色
      yAxisSplitLineColor: {type: String, default: '#FFF'},
      //y轴分割线样式
      yAxisSplitLineType: {type: String, default: 'solid'},
      //y轴单位
      yAxisSplitValueUit: {type: String, default: ''},
      //y轴小刻度显示
      yAxisAxisTick: {type: Boolean, default: false},
      //y轴显示
      yAxisLineShow: {type: Boolean, default: false},
      //y轴样式
      yAxisLineType: {type: String, default: 'solid'},
      yAxisLineColor: {type: String, default: 'red'},
      //x轴
      xAxisLineColor: {type: String, default: 'red'},
      //x轴小刻度显示
      xAxisAxisTick: {type: Boolean, default: false},
      //x轴分割线
      xAxisSplitLineShow: {type: Boolean, default: false},
      //x轴分割线颜色
      xAxisSplitLineColor: {type: String, default: '#FFF'},
      //y轴分割线样式
      xAxisSplitLineType: {type: String, default: 'solid'},
      //x轴倾斜度
      xAxisRotate: {type: Number, default: 0},
      //x轴样式
      xAxisLineType: {type: String, default: 'solid'},
      //x轴显示
      xAxisLineShow: {type: Boolean, default: false},
      //x轴name显示
      xAxisLabelShow: {type: Boolean, default: false},
      //显示 背景
      showBackground: {type: Boolean, default: false},
      //显示markpoint
      markPoint: {type: Boolean, default: false},
      //自动滚动
      autoMove: {type: Boolean, default: false},
      endDataZoom: {type: Number, default: 5},
      title: {
        type: Object, default: function () {
          return {}
        }
      },
      fontColor:{
        type: Object, default: function () {
          return {
            x:screenConfig.nameColor,
            y:screenConfig.yNameColor,
          }
        }
      },
      grid: {
        type: Object, default: function () {
          return {
            left: '10',
            top: '10',
            right: '10',
            bottom: '20'
          }
        }
      },
      dataZoom: {
        type: Array, default: function () {
          return [{type: 'slider', show: false, height: 15}]
        }
      },
      url: {
        type: String, default: ''
      },
      params: {
        type: Object, default: {}
      }
    }
);
// dom 组件
const echartsDom = ref<any>(null);

const echartsStyle = ref<any>({});
//请求返回的数据
const responseData = ref<any>();

// @ts-ignore
let {proxy} = getCurrentInstance()

//
let myEcharts: any = null;

onMounted(() => {
  initEcharts()
})

//监听查询条件
watch(() => props.params, () => {
  initEcharts();
})

let dataZoomMaxLength: number = 0;
let timer: any = null;
let startDataZoom = 0;
let endDataZoom = props.endDataZoom;
const initEcharts = () => {
  getData().then((option: any) => {
    myEcharts = proxy.$echarts.init(echartsDom.value);
    if (myEcharts) {
      myEcharts.clear();
      myEcharts.setOption(option)
      if (props.autoMove) {
        myEcharts.on('mouseover', stop)
        myEcharts.on('mouseout', goMove)
        autoMove();
      }
    }
  });
}
const autoMove = () => {
  if (timer) return
  timer = setInterval(() => {
    console.log(startDataZoom, endDataZoom, dataZoomMaxLength)

    if (endDataZoom === dataZoomMaxLength) {
      startDataZoom = 0
      endDataZoom = props.endDataZoom
      myEcharts.setOption({
        dataZoom: {
          startDataZoom, // 从头开始。
          endDataZoom
        }

      })
    } else {
      myEcharts.setOption({
        dataZoom: {
          startValue: ++startDataZoom, // 从头开始。
          endValue: ++endDataZoom
        }

      })
    }
  }, 3000);
}
const stop = (...args: any[]) => {
  console.log(args)
  clearInterval(timer)
  timer = null
}
const goMove = (...args: any[]) => {
  console.log(args)
  autoMove()
}
const getArrByKey = (data: any, k: any) => {
  let key = k || 'value';
  let res: any = [];
  if (data) {
    data.forEach(function (t: any) {
      res.push(t[key]);
    });
  }
  return res;
};

// x轴属性
const xAxis = (xData: any) => {
  let axis: any = {
    type: 'category',
    boundaryGap: false, // 紧挨边缘
    axisTick: {
      // x轴上的小刻度
      show: props.xAxisAxisTick
    },
    splitLine: {
      // 网格线
      show: props.xAxisSplitLineShow,
      lineStyle: {
        type: props.xAxisSplitLineType, // dotted 虚线 solid 实线
        color: props.xAxisSplitLineColor
      }
    },
    axisLine: {
      show: props.xAxisLineShow,
      lineStyle: {
        type: props.xAxisLineType,
        color: props.xAxisLineColor
      }
    },
    axisLabel: {
      show: props.xAxisLabelShow,
      // x轴样式
      margin: 5, // x轴距离文字距离
      interval: 0, //显示所有X轴信息
      rotate: props.xAxisRotate, //倾斜角度
      textStyle: {
        color: props.fontColor.x,
        fontSize: screenConfig.fontSizeX
      },
      rich: {
        seq: {
          color: 'white',
          backgroundColor: '#3C5068',
          lineHeight: 20,
          height: 20,
          width: 20,
          padding: 2,
          align: 'center'

        },
        seq1: {
          color: 'white',
          backgroundColor: 'red',
          lineHeight: 20,
          height: 20,
          width: 20,
          padding: 2,
          align: 'center'
        },
        seq2: {
          color: 'white',
          backgroundColor: 'orange',
          lineHeight: 20,
          height: 20,
          width: 20,
          padding: 2,
          align: 'center'
        },
        seq3: {
          color: 'white',
          backgroundColor: '#3EC26C',
          lineHeight: 20,
          height: 20,
          width: 20,
          padding: 2,
          align: 'center'
        },
        labelcolor: {
          padding: [0, 5, 0, 5],
          color: '#FFF',
          fontSize: 12
        }
      },
      inverse: props.richBar,
      formatter: function (value: string, index: number) {
        if (props.erectName) {
          let str = value.split("");
          return str.join("\n");
        } else if (props.richBar && props.richNumBar) {
          let str = "";
          switch (index) {
            case xData.length - 1:
              str = '{seq1| ' + (xData.length - index) + ' }';
              break;
            case xData.length - 2:
              str = '{seq2| ' + (xData.length - index) + ' }';
              break;
            case xData.length - 3:
              str = '{seq3| ' + (xData.length - index) + ' }';
              break;
            default:
              str = '{seq| ' + (xData.length - index) + ' }';
              break;
          }
          return str;
        } else {
          return value;
        }
      }
    },
    data: xData
  };
  if (props.horizontal) {
    axis = [
      {
        triggerEvent: true,
        show: true,
        inverse: true,
        data: getArrByKey(responseData.value, 'name'),
        axisLine: {
          show: false,
        },
        splitLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          interval: 0,
          inside: true,
          color: props.horizontalNameColor,
          margin: 0,
          padding: [0, 0, 10, 0],
          align: 'left',
          verticalAlign: 'bottom',
          formatter: function (value: any, index: any) {
            return '{title|' + value + '}';
          },
          rich: {
            title: {
              width: 50,
              fontSize: props.horizontalNameFontSize,
            },
          },
        },
      },
      {
        triggerEvent: true,
        show: true,
        inverse: true,
        data: getArrByKey(responseData.value, 'name'),
        axisLine: {
          show: false,
        },
        splitLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        axisLabel: {
          margin: 0,
          interval: 0,
          inside: true,
          padding: [0, 0, 10, 0],
          color: props.horizontalValueColor,
          fontSize: props.horizontalNameFontSize,
          align: 'right',
          verticalAlign: 'bottom',
          formatter: function (value: any, index: any) {
            return responseData.value[index].value;
          },
        },
      },
    ]
  }
  return axis;
}
/**
 * y轴属性
 */
const yAxis = () => {
  return {
    name: '',
    nameTextStyle: {
      color: props.fontColor.y,
      fontSize: screenConfig.yNameFontSize,
    },
    type: 'value',
    splitLine: {
      // 网格线
      show: props.yAxisSplitLineShow,
      lineStyle: {
        type: props.yAxisSplitLineType, // dotted 虚线 solid 实线
        color: props.yAxisSplitLineColor
      }
    },
    axisLine: {
      show: props.yAxisLineShow,
      lineStyle: {
        type: props.yAxisLineType,
        color: props.yAxisLineColor
      }
    },
    axisTick: {
      show: props.yAxisAxisTick
    },
    axisLabel: {
      show: props.yAxisLabelShow,
      //y 轴样式
      formatter: (value: any, index: any) => {
        if (props.yAxisSplitValueUit === '') {
          if (value >= 10000) {
            return `${(value / 10000).toFixed(1)}W`
          } else if (value >= 1000) {
            return `${(value / 1000).toFixed(1)}K`
          }
        }
        return `${(value)}`
      },
      color: '#A1A7B3',
      fontSize: 14,
      textStyle: {
        color: screenConfig.valueColor
      }
    }
  }
}

const tooltip = (i: number) => {
  let formatter = '{b} : {c}';
  if (i > 1) {
    formatter = '';
  }
  return {
    show: true,
    trigger: 'axis', //axis , item
    backgroundColor: 'RGBA(0, 49, 85, 1)',
    borderColor: 'rgba(0, 151, 251, 1)',
    borderWidth: 1,
    borderRadius: 0,
    textStyle: {
      color: '#BCE9FC',
      fontSize: 16,
      align: 'left',
    },
    formatter,

  }
}


const legend = () => {
  return {
    show: props.legendShow,
    orient: props.legendOrient,
    left: props.legendLeft,
    textStyle: {
      fontSize: screenConfig.legendFontSize,
      fontFamily: screenConfig.legendFontFamily,
      color: screenConfig.legendFontColor,
    },
  }
}
const getData = () => {
  return new Promise((resolve, reject) => {
        if (props.url) {
          loading.value = true;
          proxy.$http.post(props.url, props.params)
              .then((apiResponse: any) => {
                    if (apiResponse.success || apiResponse.data) {
                      //x轴数据
                      let xData: any = [];

                      let vMarkerData: any = [];

                      //series
                      let series: any = [];
                      //获取的数据
                      let echartsData = apiResponse.data.echartsData;

                      let i = 0;
                      Object.keys(echartsData).forEach((key: string) => {
                        if (i === 0) {
                          responseData.value = echartsData[key];
                          dataZoomMaxLength = echartsData[key].length;
                          for (let x = 0; x < echartsData[key].length; x++) {
                            let data = echartsData[key][x];
                            xData.push(data.name);
                            vMarkerData.push(data.value);
                          }
                        }
                        //y轴值
                        let yValue: any = [];
                        for (let x = 0; x < echartsData[key].length; x++) {
                          let data = echartsData[key][x];
                          yValue.push(data.value);
                        }
                        let mSeries: any = {
                          name: key,
                          data: yValue,
                          type: 'bar',
                          showBackground: props.showBackground,
                          barWidth: props.barWidth,
                          label: {
                            show: props.seriesLabelShow,
                            position: props.seriesLabelPosition,
                            textStyle: {
                              color: props.seriesLabelColor,
                              fontSize: screenConfig.markPointFontSize
                            }
                          },
                          symbolSize: [30, 8],
                          itemStyle: props.seriesItemStyle
                        };
                        if (props.markPoint) {
                          let datapoint = getMarkPoint(xData, vMarkerData);
                          mSeries.markPoint = {
                            symbol: 'pin',// 标记类型
                            symbolSize: 60,// 图形大小
                            itemStyle: {
                              normal: {
                                borderColor: '#000',
                                borderWidth: 0, // 标注边线线宽，单位px，默认为1
                                label: {
                                  show: true,
                                  fontSize: screenConfig.markPointFontSize,
                                  color: screenConfig.markPointFontColor,
                                },

                              }
                            },
                            data: datapoint,
                            label: {
                              normal: {
                                formatter: function (item: any) {
                                  let value = item.value;
                                  if (value >= 10000) {
                                    return (value / 10000).toFixed(2) + 'W';
                                  } else if (value > 1000) {
                                    return (value / 1000).toFixed(2) + 'K';
                                  }
                                  return value.toFixed(2);
                                }
                              }
                            }
                          };
                        }

                        if (props.customSymbol) {
                          mSeries.type = 'pictorialBar';
                          mSeries.symbolRepeat = 'fixed';
                          mSeries.symbolMargin = 4;
                          mSeries.symbol = 'rect';
                          mSeries.symbolClip = true;
                          mSeries.symbolSize = [props.barWidth, 8];
                          mSeries.symbolPosition = 'start';
                          mSeries.symbolOffset = [0, -1];
                          mSeries.z = 0;
                          mSeries.zlevel = 8;
                        }

                        if (props.singBaseModel) {
                          mSeries.itemStyle = {
                            normal: {
                              //这里是颜色
                              color: function (params: any) {
                                console.log("singBaseModel");
                                //注意，如果颜色太少的话，后面颜色不会自动循环，最好多定义几个颜色
                                if (props.barColor[params.dataIndex]) {
                                  return props.barColor[params.dataIndex];
                                } else if (props.barColor.length == 1) {
                                  return props.barColor[0];
                                } else {
                                  return '#00A3E0';
                                }
                              }
                            }
                          }
                        } else {
                          mSeries.itemStyle = {normal: {color: props.barColor[i]}};
                        }

                        if (props.barStack) {
                          mSeries.stack = "flore";
                          mSeries.itemStyle = {normal: {color: props.barColor[i]}};
                        }

                        series.push(mSeries);
                        i++;
                      });
                      let dataZoom = props.dataZoom;
                      if (props.autoMove) {
                        dataZoom = [{
                          show: false,
                          type: "slider", // 这个 dataZoom 组件是 slider 型 dataZoom 组件
                          startValue: startDataZoom, // 从头开始。
                          endValue: endDataZoom
                        }]
                      }

                      let option: any = {
                        backgroundColor: 'transparent',
                        legend: legend(),
                        tooltip: tooltip(i),
                        xAxis: xAxis(xData),
                        yAxis: yAxis(),
                        title: props.title,
                        dataZoom: dataZoom,
                        series
                      };
                      if (props.yAxisSplitValueUit != '') {
                        option.yAxis.name = props.yAxisSplitValueUit
                      }

                      if (props.richBar) {
                        option.xAxis = yAxis();
                        option.yAxis = xAxis(xData);
                      }
                      if (props.richNumBar) {
                        option.grid = {
                          left: '0',
                          top: '10',
                          containLabel: true
                        };
                        option.tooltip.trigger = 'item'
                      } else {
                        option.grid = props.grid;
                      }
                      loading.value = false;
                      resolve(option);
                    } else {
                      ElMessage.error("数据格式异常,本组件接收数据类型")
                    }
                  }
                  ,
                  (err: any) => {
                    reject(err);
                  }
              )
          ;
        } else {
          reject("无法获取请求地址");
        }
      }
  )
}
</script>